package com.gzsxy.esjy.service.core.sign.service.doc;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpUtil;

import com.alibaba.fastjson.JSON;
import com.gzsxy.esjy.common.base.exception.impl.BusinessException;
import com.gzsxy.esjy.feign.NettyFile.FileService;
import com.gzsxy.esjy.service.base.DictionaryConstants;
import com.gzsxy.esjy.service.base.dto.response.DefaultResponse;
import com.gzsxy.esjy.service.core.sign.entity.ArraignSign;
import com.gzsxy.esjy.service.core.sign.entity.ResourcesIndex;
import com.gzsxy.esjy.service.core.sign.enums.DocumentEnum;
import com.gzsxy.esjy.service.core.sign.initialize.PdfConfigArraignCardDto;
import com.gzsxy.esjy.service.core.sign.initialize.PdfConfigCache;
import com.gzsxy.esjy.service.core.sign.initialize.PdfConfigDto;
import com.gzsxy.esjy.service.core.util.IVMPMultipartFile;
import com.gzsxy.esjy.service.core.util.PdfUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangxiaolong
 * @date 2022/7/13 11:36
 */
@Component
@Slf4j
public class DocBaseService {

    @Autowired
    private PdfConfigCache pdfConfigCache;

    @Autowired
    private FileService fileService;

    @Value("${local.ip:}")
    private String pathIp;

    /**
     * 默认文书盖章
     */
    public void defaultDoSeal(ArraignSign arraignSign, String sealFilePath, File pdfFile, String pdfFileType) {
        //获取PDF水印位置信息
        List<PdfConfigDto.MarkType> markByType = pdfConfigCache.getMarkByType(arraignSign.getType());
        // 签名类型 1_seal.民警盖章 1_sign.民警签名 2_sign.在押人员 3_sign.看守所签名 3_seal. 看守所盖章
        String signType = "3_seal";
        List<PdfUtils.PdfMark> collect = markByType.stream()
                .filter(m -> m.getSignType().equals(signType))
                .map(m -> {
                            PdfUtils.PdfMark pdf = new PdfUtils.PdfMark();
                            PdfConfigDto.Position position = m.getPosition();
                            BeanUtils.copyProperties(position, pdf);
                            pdf.setContent(sealFilePath);
                            return pdf;
                        }
                ).collect(Collectors.toList());

        String sealPdfPath = String.format("%s/seal/%s%s", DictionaryConstants.PDF_TEMP_PATH, UUID.randomUUID().toString(), pdfFileType);
        File sealPdfFile = new File(sealPdfPath);
        //添加盖章
        boolean mark = PdfUtils.addPdfMark(pdfFile, sealPdfFile, collect);
        if (!mark) {
            throw BusinessException.getInstance("盖章失败");
        }

        ResourcesIndex resourcesIndex = null;
        try {
            FileInputStream fileInputStream = new FileInputStream(sealPdfFile);
            MultipartFile multipartFile = new IVMPMultipartFile("file", arraignSign.getSignName(), MediaType.APPLICATION_OCTET_STREAM_VALUE, FileCopyUtils.copyToByteArray(fileInputStream));
            //上传文件
            DefaultResponse defaultResponse = fileService.uploadFrom(multipartFile, 0);
            resourcesIndex = JSON.parseObject(JSON.toJSONString(defaultResponse.getData()), ResourcesIndex.class);

        } catch (Exception e) {
            log.error("上传盖章文件失败", e);
            throw BusinessException.getInstance("上传盖章文件失败");
        } finally {
            sealPdfFile.delete();
            pdfFile.delete();
        }
        arraignSign.setLatestFile(resourcesIndex.getFileIndex());
    }

    /**
     *
     * @param markList 默认文书叠加日期的坐标
     * @param arraignSign 需要叠加日期的文书
     * @param startTime 指定开始时间
     * @param endTime 指定结束时间
     * @param content 当前时间字符串
     */
    public void defaultDoSign(List<PdfUtils.PdfMark> markList, ArraignSign arraignSign, String startTime, String endTime, String content) {
        //默认叠加时间
        String signType = "3_sign";
        if (arraignSign.getType().equals(DocumentEnum.INTERROGATION.getType())) {
            //提讯提解证
            PdfConfigArraignCardDto arraignCardDto = pdfConfigCache.getArraignCardDto();

            String[] startTimeSplit = startTime.split(" ");
            String[] endTimeSplit = endTime.split(" ");

            int rowIndex = 1;
            for (int i = 0; i < arraignCardDto.getRowMarkMap().size(); i++) {
                PdfConfigDto.MarkType markType = arraignCardDto.getRowMarkMap().get(i);
                PdfUtils.PdfMark pdfMark = new PdfUtils.PdfMark();
                PdfConfigDto.Position position = markType.getPosition();
                BeanUtils.copyProperties(position, pdfMark);
                if (rowIndex > DictionaryConstants.NUMBER_1) {
                    pdfMark.setX(pdfMark.getX() - (arraignCardDto.getRowConfig().getRowInterval() * (rowIndex - 1)));
                }

                if (i == 0) {
                    pdfMark.setContent(startTimeSplit[0]);
                } else if (i == 1) {
                    pdfMark.setContent(startTimeSplit[1]);
                } else if (i == 2) {
                    pdfMark.setContent(endTimeSplit[0]);
                } else if (i == 3) {
                    pdfMark.setContent(endTimeSplit[1]);
                }

                markList.add(pdfMark);
            }
        } else {
            List<PdfConfigDto.MarkType> markTypes = pdfConfigCache.getMarkByType(arraignSign.getType());
            LocalDateTime localDateTime = DateUtil.parseLocalDateTime(content);
            for (int i = 0; i < markTypes.size(); i++) {
                PdfConfigDto.MarkType markType = markTypes.get(i);
                //排除盖章的操作
                if (!markType.getSignType().equals(signType)) {
                    continue;
                }
                PdfUtils.PdfMark pdfMark = new PdfUtils.PdfMark();
                BeanUtils.copyProperties(markType.getPosition(), pdfMark);
                if (i == 1) {
                    pdfMark.setContent(localDateTime.getYear() + "");
                } else if (i == 2) {
                    pdfMark.setContent(localDateTime.getMonthValue() + "");
                } else if (i == 3) {
                    pdfMark.setContent(localDateTime.getDayOfMonth() + "");
                }
                markList.add(pdfMark);
            }
        }
    }

    /**
     * 叠加日期
     */
    public void defaultPdfOverlayDate(ArraignSign arraignSign, File pdfFile,String sealFileType, List<PdfUtils.PdfMark> markList) {
        String outPath = String.format("%s/seal/%s%s", DictionaryConstants.PDF_TEMP_PATH, UUID.randomUUID().toString(), sealFileType);
        File outFile = new File(outPath);
        boolean mark = PdfUtils.addPdfMark(pdfFile, outFile, markList);
        if (!mark) {
            log.error("叠加日期失败");
            throw BusinessException.getInstance("叠加日期失败");
        }
        ResourcesIndex resourcesIndex =null;
        //上传文件
        try (FileInputStream fileInputStream = new FileInputStream(outFile)) {
            //告知浏览器这是一个字节流，浏览器处理字节流的默认方式就是下载
            MultipartFile multipartFile = new IVMPMultipartFile("file", arraignSign.getSignName(),
                    MediaType.APPLICATION_OCTET_STREAM_VALUE, FileCopyUtils.copyToByteArray(fileInputStream));

            DefaultResponse defaultResponse = fileService.uploadFrom(multipartFile, 0);
            resourcesIndex = JSON.parseObject(JSON.toJSONString(defaultResponse.getData()), ResourcesIndex.class);
        } catch (Exception e) {
            log.error("上传文件失败，", e);
            throw BusinessException.getInstance("上传文件失败");
        } finally {
            outFile.delete();
            pdfFile.delete();
        }
        arraignSign.setLatestFile(resourcesIndex.getFileIndex());
    }

    /**
     * 下载文书
     *
     * @param url  文件URL
     * @param file 本地保存文件
     */
    private void downloadSignFile(String url, File file) {
        try {
//            String fileHttpPath = String.format("http://%s/file-server/resources/%s",  this.pathIp, url);
//            byte[] bytes = HttpUtil.downloadBytes(fileHttpPath);
            byte[] bytes = fileService.downloadFile(url);
            FileUtil.writeBytes(bytes,file);
        } catch (Exception e) {
            log.warn("downloadSignFile 文书下载失败：" + e.getMessage());
            throw BusinessException.getInstance("文书下载失败");
        }
    }



}
